
#include "lvgl_init.h"

monitor_t g_monitor;
lvgl_context_t g_lvglContext_t;

static volatile bool g_inited = false;
static volatile bool g_quit_qry = false;

void buffer_trans(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p)
{
	lv_coord_t hres = disp->rotated == 0 ? disp->hor_res : disp->ver_res;
	lv_coord_t vres = disp->rotated == 0 ? disp->ver_res : disp->hor_res;

	/*Return if the area is out the screen*/
	if (area->x2 < 0 || area->y2 < 0 || area->x1 > hres - 1 || area->y1 > vres - 1) {

		lv_disp_flush_ready(disp);
		return;
	}

	int32_t y;
#if LV_COLOR_DEPTH != 24 && LV_COLOR_DEPTH != 32    /*32 is valid but support 24 for backward compatibility too*/
	int32_t x;
	for (y = area->y1; y <= area->y2 && y < disp->ver_res; y++) {
		for (x = area->x1; x <= area->x2; x++) {
			g_monitor.tft_fb[y * disp->hor_res + x] = lv_color_to32(*color_p);
			color_p++;
		}

	}
#else
    if (g_lvglContext_t.disp_drv.direct_mode == 1) {
        memcpy(g_monitor.tft_fb, color_p, sizeof(g_monitor.tft_fb));
    }
    else
    {
        uint32_t w = lv_area_get_width(area);
        for (y = area->y1; y <= area->y2 && y < disp->ver_res; y++) {
            memcpy(&g_monitor.tft_fb[y * DISP_HOR_RES + area->x1], color_p, w * sizeof(lv_color_t));
            color_p += w;
        }
    }
#endif

	g_monitor.refr_qry = true;

	/*IMPORTANT! It must be called to tell the system the flush is ready*/
	lv_disp_flush_ready(disp);
}

void mouse_read(lv_indev_drv_t* indev, lv_indev_data_t* data)
{
	data->state = g_lvglContext_t.mouse_state;
	data->point = g_lvglContext_t.mouse_point;
}

void add_input_devices_to_group()
{
	lv_group_t* group = lv_group_get_default();
	if (!group)
	{
		LV_LOG_WARN(
			"The default group object is NULL. Create a new group object "
			"and set it to default instead.");

		group = lv_group_create();
		if (group)
		{
			lv_group_set_default(group);
		}
	}

	LV_ASSERT_MSG(group, "Cannot obtain an available group object.");

	lv_indev_set_group(g_lvglContext_t.indev_mouse, group);
}

void lvgl_hal_init(void)
{
    /* 初始化显示缓冲区 */ 
	lv_disp_draw_buf_init(&g_lvglContext_t.draw_buf, g_lvglContext_t.buf1, g_lvglContext_t.buf2, DISP_HOR_RES * DISP_VER_RES);

    /* 初始化显示驱动 */ 
	lv_disp_drv_init(&g_lvglContext_t.disp_drv);                   // 基础初始化
	g_lvglContext_t.disp_drv.flush_cb = buffer_trans;             // 缓冲区刷新回调
	g_lvglContext_t.disp_drv.draw_buf = &g_lvglContext_t.draw_buf; // 设置显示buffer
	g_lvglContext_t.disp_drv.hor_res = DISP_HOR_RES;               // 水平分辨率
	g_lvglContext_t.disp_drv.ver_res = DISP_VER_RES;               // 垂直分辨率
	g_lvglContext_t.disp_drv.direct_mode = 1;
	
	/* 注册驱动 */ 
	lv_disp_drv_register(&g_lvglContext_t.disp_drv);      

    /* 外设初始化和注册 */ 
	lv_indev_drv_init(&g_lvglContext_t.mouse_driver);             // 基础初始化
	g_lvglContext_t.mouse_driver.type = LV_INDEV_TYPE_POINTER;    // 设置设备驱动类型为，类似指针的设备
	g_lvglContext_t.mouse_driver.read_cb = mouse_read;            // 读取回调
    lv_indev_drv_register(&g_lvglContext_t.mouse_driver);         // 注册驱动

}